﻿/**
 * Copyright (C) 2012-2013 original author and authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NGuice.Inject.Spi
{
    //complete!
    /// <summary>
    /// 支持一个自定义的BindingTargetVisitor扩展的一部分的提供者接口。当一个
    /// 扩展绑定一个提供者实例，提供者能够实现此接口以便允许用户使用
    /// <code>
    /// Binding#AcceptTargetVisitor(BindingTargetVisitor)
    /// </code>
    /// 方法访问一个为扩展设置的自定义访问者。一个典型的具有扩展的实现应该如下：
    /// <code>
    /// V AcceptExtensionVisitor<V, B>(BindingTargetVisitor<B, V> visitor, ProviderInstanceBinding<B> binding) {
    /// if(visitor is MyCustomExtensionVisitor) {
    ///     return ((MyCustomExtensionVisitor<B, V>)visitor).visitCustomExtension(customProperties, binding);
    /// } else {
    ///     return visitor.visit(binding);
    /// }
    /// }
    /// </code>
    /// 例子中的MyCustomExtensionVisitor是一个提供者扩展，用户能够使用此扩展通知自定义扩展信息。此访问者接口
    /// 必须扩展自BindingTargetVisitor
    /// </summary>
    public interface IProviderWithExtensionVisitor<T> : IProvider<T>
    {
        /// <summary>
        /// 指示扩展决定如果访问者是一个自定义扩展访问者实例，使用相应方法访问。如果访问者
        /// 不是自定义扩展访问者，此方法必须调用visitor.Visit(binding).通常，此方法的类型
        /// 参数不关联于提供者类型。根据实践，B类型将总是T的超类型
        /// </summary>
        /// <typeparam name="B"></typeparam>
        /// <typeparam name="V"></typeparam>
        /// <param name="visitor"></param>
        /// <param name="binding"></param>
        /// <returns></returns>
        V AcceptExtensionVisitor<B, V>(IBindingTargetVisitor<B, V> visitor, IProviderInstanceBinding<B> binding);
    }
}
